const fs = require('fs');
const path = require('path');
const { transcribeAudio } = require('./convert');

class AudioProcessor {
  constructor(htmlFilePath, voiceDir, overwrite = false) {
    this.htmlFilePath = htmlFilePath;
    this.voiceDir = voiceDir;
    this.overwrite = overwrite;
    this.audioLinks = [];
    
    // 生成输出文件路径 msg_txt.html
    this.outputFilePath = htmlFilePath.replace('.htm', '_txt.html');
  }

  // 解析HTML文件，提取所有音频播放链接
  parseAudioLinks() {
    try {
      const htmlContent = fs.readFileSync(this.htmlFilePath, 'utf8');
      
      // 使用正则表达式匹配所有的PlayMyWav调用
      const audioRegex = /onClick="return PlayMyWav\(this,'([^']+)'\);"/g;
      let match;
      
      while ((match = audioRegex.exec(htmlContent)) !== null) {
        const audioId = match[1];
        const audioPath = path.join(this.voiceDir, `${audioId}.wav`);
        
        // 检查文件是否存在
        if (fs.existsSync(audioPath)) {
          // 检查是否已经转录过
          const transcriptionExists = this.checkIfTranscribed(htmlContent, audioId);
          
          if (!transcriptionExists) {
            this.audioLinks.push({
              id: audioId,
              path: audioPath,
              originalMatch: match[0]
            });
          } else {
            console.log(`⏭️  跳过已转录的音频: ${audioId}`);
          }
        } else {
          console.warn(`音频文件不存在: ${audioPath}`);
        }
      }
      
      console.log(`找到 ${this.audioLinks.length} 个待转录音频文件`);
      return this.audioLinks;
    } catch (error) {
      console.error('解析HTML文件失败:', error);
      throw error;
    }
  }

  // 检查音频是否已经转录过
  checkIfTranscribed(htmlContent, audioId) {
    // 先检查输出文件是否存在且不允许覆盖
    if (fs.existsSync(this.outputFilePath) && !this.overwrite) {
      const outputContent = fs.readFileSync(this.outputFilePath, 'utf8');
      const escapedId = audioId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
      const transcriptionPattern = new RegExp(
        `onClick="return PlayMyWav\\(this,'${escapedId}'\\);"[\\s\\S]*?\\[🎵语音内容\\]:`,
        'g'
      );
      return transcriptionPattern.test(outputContent);
    }
    
    // 如果输出文件不存在或允许覆盖，检查原始文件是否已处理
    const escapedId = audioId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    const transcriptionPattern = new RegExp(
      `onClick="return PlayMyWav\\(this,'${escapedId}'\\);"[\\s\\S]*?\\[语音内容\\]:`,
      'g'
    );
    return transcriptionPattern.test(htmlContent);
  }

  // 批量转换音频文件为文本
  async convertAllAudio() {
    const results = [];
    
    for (let i = 0; i < this.audioLinks.length; i++) {
      const audio = this.audioLinks[i];
      console.log(`正在转换 (${i + 1}/${this.audioLinks.length}): ${audio.id}`);
      
      try {
        const text = await transcribeAudio(audio.path);
        results.push({
          ...audio,
          text: text.trim()
        });
        
        // 添加延迟以避免API限制
        if (i < this.audioLinks.length - 1) {
          await new Promise(resolve => setTimeout(resolve, 1000));
        }
      } catch (error) {
        console.error(`转换失败 ${audio.id}:`, error);
        results.push({
          ...audio,
          text: '[转换失败]'
        });
      }
    }
    
    return results;
  }

  // 将转换结果插入到HTML文件中
  insertTextToHtml(conversionResults) {
    try {
      // 读取原始HTML文件内容
      let htmlContent = fs.readFileSync(this.htmlFilePath, 'utf8');
      
      // 检查输出文件是否存在
      let outputExists = fs.existsSync(this.outputFilePath);
      
      if (outputExists && !this.overwrite) {
        console.log(`⏭️  输出文件已存在，跳过处理: ${this.outputFilePath}`);
        return fs.readFileSync(this.outputFilePath, 'utf8');
      }
      
      if (outputExists && this.overwrite) {
        console.log(`🔄 覆盖模式，将重新生成: ${this.outputFilePath}`);
      }
      
      // 如果有转换结果，插入到HTML中
      if (conversionResults.length > 0) {
        conversionResults.forEach(result => {
          // 查找音频播放链接的位置 - 使用更宽松的正则表达式来匹配多行HTML结构
          const escapedId = result.id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
          const audioLinkRegex = new RegExp(
            `(<div class="content">\\s*&nbsp;&nbsp;<a[^>]*onClick="return PlayMyWav\\(this,'${escapedId}'\\);[^>]*>\\s*\\[点击播放语音\\]</a[^>]*>\\s*</div>)`,
            'gms'
          );
          
          // 创建包含转换文本的新HTML结构，使用新的标识符
          const textDiv = `
    <div class="content" style="margin-left: 20px; color: #666; font-style: italic;">
      <span class="MsgHistory">&nbsp;&nbsp;[🎵语音内容]: ${result.text}</span>
    </div>`;
          
          const replacement = `$1${textDiv}`;
          
          htmlContent = htmlContent.replace(audioLinkRegex, replacement);
        });
      }
      
      // 保存到新的输出文件
      fs.writeFileSync(this.outputFilePath, htmlContent);
      console.log(`✅ 已生成转录文件: ${this.outputFilePath}`);
      console.log(`📁 原始文件保留: ${this.htmlFilePath}`);
      
      return htmlContent;
    } catch (error) {
      console.error('插入文本到HTML失败:', error);
      throw error;
    }
  }

  // 主处理流程
  async process() {
    try {
      console.log('开始处理音频转文本...');
      
      // 1. 解析HTML中的音频链接
      this.parseAudioLinks();
      
      if (this.audioLinks.length === 0) {
        console.log('没有找到音频文件，处理完成。');
        return;
      }
      
      // 2. 转换所有音频文件
      console.log('开始转换音频文件...');
      const results = await this.convertAllAudio();
      
      // 3. 将文本插入HTML
      console.log('将转换结果插入HTML...');
      this.insertTextToHtml(results);
      
      console.log('处理完成！');
      
      // 输出转换统计
      const successCount = results.filter(r => r.text !== '[转换失败]').length;
      console.log(`转换统计: 成功 ${successCount}/${results.length}`);
      
      return results;
    } catch (error) {
      console.error('处理过程中发生错误:', error);
      throw error;
    }
  }
}

module.exports = AudioProcessor;